﻿// <!--Copyright (c) 2012
//    Isura Edirisinghe

//        Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.-->
 
using System;
using System.ComponentModel;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;

namespace Fixtures
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private FixtureFileManager _fixtureFileMgr;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = "fxt";
            dlg.Filter = "Fixture Files (*.fxt)|*.fxt|All Files (*.*)|*.*";

            Nullable<bool> result = dlg.ShowDialog();
            if (result == true)
            {
                FilePath.Text = dlg.FileName;

                _fixtureFileMgr = new FixtureFileManager(dlg.FileName);
                _fixtureFileMgr.ReadMatchData();
                Matches matches = (Matches) Resources["matches"];
                matches.Clear();
                foreach (MatchData md in _fixtureFileMgr.MatchData)
                    matches.Add(new Match(md, _fixtureFileMgr));
            }
        }

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            if (_fixtureFileMgr != null)
            {
                _fixtureFileMgr.WriteMatchData();
            }
        }

        private void ExitButton_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }
    }

    public class Matches : ObservableCollection<Match>
    {
        // Wrapper class so we can bind data in Xmal. 
    }

    public class FixtureFileManager
    {
        public readonly DateTime DayZero;
 
        private List<Byte> _contents;
        private List<MatchData> _matches;
        private String _filePath;

        public FixtureFileManager(String filePath)
        {
            _filePath = filePath;
            _contents = new List<byte>(File.ReadAllBytes(filePath));    // To do: Handle IO exceptions
            _matches = new List<MatchData>();
            Int32 startYear = ParseStartYear(filePath);
            DayZero = new DateTime(startYear, 3, 31);
        }

        public IEnumerable<MatchData> MatchData { get { return _matches; } }
 
        public void ReadMatchData()
        {
            Debug.Assert(_matches.Count == 0);

            Int32 currentAddress = 0;
            Int32 currentIndex = 0;
            Boolean foundMatch = false;
            Boolean firstMatch = true;            

            while (currentAddress < _contents.Count)
            {
                Byte currentByte = _contents[currentAddress];

                // Possible marker, check if it signals a new match. This method should work all the time.
                if (firstMatch && currentByte == 0x65 || currentByte == 0x80)
                {
                    Int32 tempAddress = currentAddress;
                    tempAddress += 6;

                    if (_contents[tempAddress] == 0x34 && _contents[tempAddress + 1] == 0x77)
                        foundMatch = true;
                }

                if (foundMatch)
                {
                    // the current address should be the marker 0x80 (or 0x65 for first match).
                    MatchData data = new MatchData();
                    data.Index = currentIndex++;
                    data.StartAddress = currentAddress++;

                    data.Format = _contents[currentAddress++];
                    data.MatchInSeries = _contents[currentAddress++];
                    data.SeriesLength = _contents[currentAddress++];

                    currentAddress += 26;
                    data.HostLSB = _contents[currentAddress++];
                    data.HostMSB = _contents[currentAddress++];
                    data.VisitorLSB = _contents[currentAddress++];
                    data.VisitorMSB = _contents[currentAddress++];

                    currentAddress += 2;
                    data.DayLSB = _contents[currentAddress++];
                    data.DayMSB = _contents[currentAddress];

                    data.ChangedFCFToTest = false;

                    _matches.Add(data);

                    foundMatch = false;
                    firstMatch = false;
                }

                currentAddress++;
            }
        }

        public void WriteMatchData()
        {
            for (Int32 i = 0; i < _matches.Count; i++)
            {
                MatchData md = _matches[i];

                Int32 currentAddress = md.StartAddress + 1;
                _contents[currentAddress++] = md.Format;
                _contents[currentAddress++] = md.MatchInSeries;
                _contents[currentAddress++] = md.SeriesLength;
                
                currentAddress += 26;
                _contents[currentAddress++] = md.HostLSB;
                _contents[currentAddress++] = md.HostMSB;
                _contents[currentAddress++] = md.VisitorLSB;
                _contents[currentAddress++] = md.VisitorMSB;

                if (md.ChangedFCFToTest)
                {
                    Int32 addedBytes = InsertFillerBytes(md);
                    Debug.Assert(addedBytes > 0);
                    AdjustRemainingStartAddresses(addedBytes, i + 1);
                    md.ChangedFCFToTest = false;
                }
            }

            File.WriteAllBytes(_filePath, _contents.ToArray());
        }

        private Int32 InsertFillerBytes (MatchData md)
        {
            Int32 addressDay1 = md.StartAddress + 36;
            Debug.Assert(md.DayLSB == _contents[addressDay1]);
            Debug.Assert(md.DayMSB == _contents[addressDay1 + 1]);

            Int32 day1 = md.DayLSB + md.DayMSB*256;
            
            Int32 addressDay2 = FindAddressOfDay(day1 + 1, addressDay1);

            // collect filler bytes sequence between day 2 and day 3
            List<byte> fillerBytes = new List<byte>();
            Int32 addressDay3 =  FindAddressOfDay(day1 + 2, addressDay2);
            for (Int32 currentAddress = addressDay2 + 2; currentAddress < addressDay3 ; currentAddress++)
            {
                fillerBytes.Add(_contents[currentAddress]);
            }

            Int32 addressDay4 = FindAddressOfDay(day1 + 3, addressDay3);
            Int32 addressDay5 = FindAddressOfDay(day1 + 4, addressDay4);

            Int32 removeQty = addressDay5 - addressDay4 - 2;
            Int32 addQty = fillerBytes.Count;
            Int32 totalAdded = addQty - removeQty;
            Debug.Assert(totalAdded > 0);

            // add filler after day 4
            _contents.RemoveRange(addressDay4 + 2, removeQty);
            _contents.InsertRange(addressDay4 + 2, fillerBytes);

            // must recalculate address of day 5 after filler insertion
            addressDay5 = FindAddressOfDay(day1 + 4, addressDay4);
            Int32 addressDay6 = FindAddressOfDay(day1 + 5, addressDay5);

            removeQty = addressDay6 - addressDay5 - 2;
            addQty = fillerBytes.Count;
            Debug.Assert( addQty - removeQty > 0);
            totalAdded += addQty - removeQty;
            Debug.Assert(totalAdded > 0);

            // add filler after day 5
            _contents.RemoveRange(addressDay5 + 2, removeQty);
            _contents.InsertRange(addressDay5 + 2, fillerBytes);

            return totalAdded;
        }

        private Int32 FindAddressOfDay(Int32 day, Int32 startAddress)
        {
            for (Int32 currentAddress = startAddress; ; currentAddress++)
            {
                Byte b1 = _contents[currentAddress];
                Byte b2 = _contents[currentAddress + 1];
                Int32 n = b1 + b2 * 256;

                if (n == day)
                {
                    return currentAddress;
                }
            }
        }

        private void AdjustRemainingStartAddresses(Int32 adjustment, Int32 startIndex)
        {
            for (Int32 i = startIndex; i < _matches.Count; i++)
            {
                _matches[i].StartAddress += adjustment;
            }
        }

        private Int32 ParseStartYear(String filePath)
        {
            // Last 2 characters of fixture file should be 2 digit year (i.e 2012 -> 12).

            Int32 startYear = 2012;
            String fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);

            if (fileName.Length >= 2)
            {
                try
                {
                    String fileSuffix = fileName.Substring(fileName.Length - 2);
                    startYear = 2000 + Int32.Parse(fileSuffix);
                }
                catch (FormatException)
                {
                	// OK: we return default value
                }
            }

            return startYear;
        }
    }

    public class Match : INotifyPropertyChanged
    {
        private MatchData _matchData;
        private readonly FixtureFileManager _owner;
        private readonly Int32 _index;
        private readonly DateTime _date;
        private MatchFormat _format;
        private Byte _matchInSeries;
        private Byte _seriesLength;
        private Team _hostTeam;
        private Team _visitorTeam;

        public Match(MatchData matchData, FixtureFileManager owner)
        {
            _matchData = matchData;
            _owner = owner;

            _index = matchData.Index;
            Int32 dayOffset = _matchData.DayLSB + _matchData.DayMSB * 256;
            _date = ConvertToDate(dayOffset);

            _format = (MatchFormat)_matchData.Format;
            _matchInSeries = _matchData.MatchInSeries;
            _seriesLength = _matchData.SeriesLength;

            //if ( (Format != MatchFormat.Test && Format != MatchFormat.ODI && Format != MatchFormat.T20I)
            //    || (Format == MatchFormat.T20I && MatchInSeries == 0xFF && SeriesLength == 0xFF) )
            //{
            //    _matchInSeries = 0;
            //    _seriesLength = 0;
            //}

            InitializeTeams();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public Int32 StartAddress { get { return _matchData.StartAddress; } }

        public Int32 Index
        {
            get { return _index; }
        }

        public DateTime Date
        {
            get { return _date; }
        }

        public MatchFormat Format
        {
            get { return _format; }
            set
            {
                if (value == MatchFormat.Test && _format == MatchFormat.FCF)
                    _matchData.ChangedFCFToTest = true;

                _format = value;
                _matchData.Format = (Byte)_format;
                NotifyPropertyChanged("Format");
            }
        }

        public Byte MatchInSeries
        {
            get { return _matchInSeries; }
            set
            {
                _matchInSeries = value;
                _matchData.MatchInSeries = _matchInSeries;
                NotifyPropertyChanged("MatchInSeries");
            }
        }

        public Byte SeriesLength
        {
            get { return _seriesLength; }
            set
            {
                _seriesLength = value;
                _matchData.SeriesLength = _seriesLength;
                NotifyPropertyChanged("SeriesLength");
            }
        }

        public Team HostTeam
        {
            get { return _hostTeam; }
            set
            {
                _hostTeam = value;
                Int32 code = (Int32)_hostTeam.DefaultTeamCode;
                _matchData.HostMSB = (Byte)(code / 256);
                _matchData.HostLSB = (Byte)(code % 256);
                NotifyPropertyChanged("HostTeam");
            }
        }

        public Team VisitorTeam
        {
            get { return _visitorTeam; }
            set
            {
                _visitorTeam = value;
                Int32 code = (Int32)_visitorTeam.DefaultTeamCode;
                _matchData.VisitorMSB= (Byte)(code / 256);
                _matchData.VisitorLSB = (Byte)(code % 256);
                NotifyPropertyChanged("VisitorTeam");
            }
        }

        private void NotifyPropertyChanged(String name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        private DateTime ConvertToDate(Int32 dayOffset)
        {
            DateTime date = _owner.DayZero.AddDays(dayOffset);

            // Fixture file format doesn't assume leap years. so March dates are 1 day behind on leap years.
            if (DateTime.IsLeapYear(date.Year) && date.Month == 3)
            {
                date = date.AddDays(1);
            }

            return date;
        }

        private void InitializeTeams()
        {
            Int32 hostTeamCode = _matchData.HostLSB + _matchData.HostMSB * 256;
            Int32 visitorTeamCode = _matchData.VisitorLSB + _matchData.VisitorMSB * 256;

            if (Format == MatchFormat.ODIWC)
            {
                _hostTeam = Team.FindBy((ODIWCTeamCode)hostTeamCode);
                _visitorTeam = Team.FindBy((ODIWCTeamCode)visitorTeamCode);
            }
            else if (Format == MatchFormat.T20WC)
            {
                _hostTeam = Team.FindBy((T20WCTeamCode)hostTeamCode);
                _visitorTeam = Team.FindBy((T20WCTeamCode)visitorTeamCode);
            }
            else
            {
                _hostTeam = Team.FindBy((DefaultTeamCode)hostTeamCode);
                _visitorTeam = Team.FindBy((DefaultTeamCode)visitorTeamCode);
            }
        }
    }

    public class MatchData
    {
        public Int32 Index { get; set; }
        public Int32 StartAddress { get; set; }
        public Byte Format { get; set; }
        public Byte MatchInSeries { get; set; }
        public Byte SeriesLength { get; set; }
        public Byte HostLSB { get; set; }
        public Byte HostMSB { get; set; }
        public Byte VisitorLSB { get; set; }
        public Byte VisitorMSB { get; set; }
        public Byte DayLSB { get; set; }
        public Byte DayMSB { get; set; }
        public Boolean ChangedFCFToTest { get; set; }
    }

    public class Team : IComparable<Team>, IComparable
    {
        public static Team Australia;
        public static Team Bangladesh;
        public static Team England;
        public static Team India;
        public static Team NewZealand;
        public static Team Pakistan;
        public static Team SouthAfrica;
        public static Team SriLanka;
        public static Team WestIndies;
        public static Team Zimbabwe;

        public static Team TBD;

        public static Team Afghanistan;
        public static Team Kenya;
        public static Team Ireland;
        public static Team Netherlands;
        public static Team UAE;

        public static Team MCC;
        public static Team Lancashire;
        public static Team Warwickshire;
        public static Team Durham;
        public static Team Somerset;
        public static Team Sussex;
        public static Team Nottinghamshire;
        public static Team Worcestershire;
        public static Team Middlesex;
        public static Team Surrey;
        public static Team Yorkshire;
        public static Team Hampshire;
        public static Team Northamptonshire;
        public static Team Gloucestershire;
        public static Team Derbyshire;
        public static Team Glamorgan;
        public static Team Essex;
        public static Team Kent;
        public static Team Leicestershire;

        private static List<Team> _teams;
        private static Dictionary<DefaultTeamCode, Team> _teamsByDefaultCode;
        private static Dictionary<ODIWCTeamCode, Team> _teamsByODIWCCode;
        private static Dictionary<T20WCTeamCode, Team> _teamsByT20WCCode;

        static Team()
        {
            Australia = new Team("Australia", DefaultTeamCode.Australia, ODIWCTeamCode.Australia, T20WCTeamCode.Australia);
            Bangladesh = new Team("Bangladesh", DefaultTeamCode.Bangladesh, ODIWCTeamCode.Bangladesh, T20WCTeamCode.Bangladesh);
            England = new Team("England", DefaultTeamCode.England, ODIWCTeamCode.England, T20WCTeamCode.England);
            India = new Team("India", DefaultTeamCode.India, ODIWCTeamCode.India, T20WCTeamCode.India);
            NewZealand = new Team("New Zealand", DefaultTeamCode.NewZealand, ODIWCTeamCode.NewZealand, T20WCTeamCode.NewZealand);
            Pakistan = new Team("Pakistan", DefaultTeamCode.Pakistan, ODIWCTeamCode.Pakistan, T20WCTeamCode.Pakistan);
            SouthAfrica = new Team("South Africa", DefaultTeamCode.SouthAfrica, ODIWCTeamCode.SouthAfrica, T20WCTeamCode.SouthAfrica);
            SriLanka = new Team("Sri Lanka", DefaultTeamCode.SriLanka, ODIWCTeamCode.SriLanka, T20WCTeamCode.SriLanka);
            WestIndies = new Team("West Indies", DefaultTeamCode.WestIndies, ODIWCTeamCode.WestIndies, T20WCTeamCode.WestIndies);
            Zimbabwe = new Team("Zimbabwe", DefaultTeamCode.Zimbabwe, ODIWCTeamCode.Zimbabwe, T20WCTeamCode.Zimbabwe);

            TBD = new Team("T.B.D.", DefaultTeamCode.NotValid, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            
            Afghanistan = new Team("Afghanistan", DefaultTeamCode.NotValid, ODIWCTeamCode.NotValid, T20WCTeamCode.Afghanistan);
            Kenya = new Team("Kenya", DefaultTeamCode.NotValid, ODIWCTeamCode.Kenya, T20WCTeamCode.NotValid);
            Ireland = new Team("Ireland", DefaultTeamCode.NotValid, ODIWCTeamCode.Ireland, T20WCTeamCode.Ireland);
            Netherlands = new Team("Netherlands", DefaultTeamCode.NotValid, ODIWCTeamCode.Netherlands, T20WCTeamCode.NotValid);
            UAE = new Team("UAE", DefaultTeamCode.NotValid, ODIWCTeamCode.UAE, T20WCTeamCode.NotValid);

            MCC = new Team("MCC", DefaultTeamCode.MCC, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Lancashire = new Team("Lancashire", DefaultTeamCode.Lancashire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Warwickshire = new Team("Warwickshire", DefaultTeamCode.Warwickshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Durham = new Team("Durham", DefaultTeamCode.Durham, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Somerset = new Team("Somerset", DefaultTeamCode.Somerset, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Sussex = new Team("Sussex", DefaultTeamCode.Sussex, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Nottinghamshire = new Team("Nottinghamshire", DefaultTeamCode.Nottinghamshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Worcestershire = new Team("Worcestershire", DefaultTeamCode.Worcestershire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Middlesex = new Team("Middlesex", DefaultTeamCode.Middlesex, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Surrey = new Team("Surrey", DefaultTeamCode.Surrey, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Yorkshire = new Team("Yorkshire", DefaultTeamCode.Yorkshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Hampshire = new Team("Hampshire", DefaultTeamCode.Hampshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Northamptonshire = new Team("Northamptonshire", DefaultTeamCode.Northamptonshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Gloucestershire = new Team("Gloucestershire", DefaultTeamCode.Gloucestershire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Derbyshire = new Team("Derbyshire", DefaultTeamCode.Derbyshire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Glamorgan = new Team("Glamorgan", DefaultTeamCode.Glamorgan, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Essex = new Team("Essex", DefaultTeamCode.Essex, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Kent = new Team("Kent", DefaultTeamCode.Kent, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);
            Leicestershire = new Team("Leicestershire", DefaultTeamCode.Leicestershire, ODIWCTeamCode.NotValid, T20WCTeamCode.NotValid);

            _teams = new List<Team>();
            _teamsByDefaultCode = new Dictionary<DefaultTeamCode, Team>();
            _teamsByODIWCCode = new Dictionary<ODIWCTeamCode, Team>();
            _teamsByT20WCCode = new Dictionary<T20WCTeamCode, Team>();

            _teams.Add(Australia);
            _teams.Add(Bangladesh);
            _teams.Add(England);
            _teams.Add(India);
            _teams.Add(NewZealand);
            _teams.Add(Pakistan);
            _teams.Add(SouthAfrica);
            _teams.Add(SriLanka);
            _teams.Add(WestIndies);
            _teams.Add(Zimbabwe);

            _teams.Add(TBD);

            _teams.Add(Afghanistan);
            _teams.Add(Kenya);
            _teams.Add(Ireland);
            _teams.Add(Netherlands);
            _teams.Add(UAE);

            _teams.Add(MCC);
            _teams.Add(Lancashire);
            _teams.Add(Warwickshire);
            _teams.Add(Durham);
            _teams.Add(Somerset);
            _teams.Add(Sussex);
            _teams.Add(Nottinghamshire);
            _teams.Add(Worcestershire);
            _teams.Add(Middlesex);
            _teams.Add(Surrey);
            _teams.Add(Yorkshire);
            _teams.Add(Hampshire);
            _teams.Add(Northamptonshire);
            _teams.Add(Gloucestershire);
            _teams.Add(Derbyshire);
            _teams.Add(Glamorgan);
            _teams.Add(Essex);
            _teams.Add(Kent);
            _teams.Add(Leicestershire);

            foreach (Team t in _teams)
            {
                if (t.DefaultTeamCode != DefaultTeamCode.NotValid)
                    _teamsByDefaultCode.Add(t.DefaultTeamCode, t);
                
                if (t.ODIWCTeamCode != ODIWCTeamCode.NotValid)
                    _teamsByODIWCCode.Add(t.ODIWCTeamCode, t);
                
                if (t.T20WCTeamCode != T20WCTeamCode.NotValid)
                    _teamsByT20WCCode.Add(t.T20WCTeamCode, t);
            }
        }

        private Team(String name, DefaultTeamCode defaultCode, ODIWCTeamCode ODICode, T20WCTeamCode T20Code)
        {
            Name = name;
            DefaultTeamCode = defaultCode;
            ODIWCTeamCode = ODICode;
            T20WCTeamCode = T20Code;
        }

        public static List<Team> Teams { get { return _teams; } } 
        public String Name { get; private set; }
        public DefaultTeamCode DefaultTeamCode { get; private set; }
        public ODIWCTeamCode ODIWCTeamCode { get; private set; }
        public T20WCTeamCode T20WCTeamCode { get; private set; }

        public static Team FindBy(DefaultTeamCode defaultCode)
        {
            return _teamsByDefaultCode.ContainsKey(defaultCode) ? _teamsByDefaultCode[defaultCode] : TBD;
        }

        public static Team FindBy(ODIWCTeamCode ODICode)
        {
            return _teamsByODIWCCode.ContainsKey(ODICode) ? _teamsByODIWCCode[ODICode] : TBD;
        }

        public static Team FindBy(T20WCTeamCode T20Code)
        {
            return _teamsByT20WCCode.ContainsKey(T20Code) ? _teamsByT20WCCode[T20Code] : TBD;
        }

        public override String ToString()
        {
            return Name;
        }

        public int CompareTo(Team other)
        {
            return ToString().CompareTo(other.ToString());
        }

        public int CompareTo(Object other)
        {
            return CompareTo((Team)other);
        }
    }

    public enum MatchFormat : byte
    {
        ODIWC = 9,
        T20WC,
        Tri,
        Test,
        ODI,
        FCF,
        ODF,
        T20I = 18
    };

    public enum DefaultTeamCode : int
    {
        Australia = 43,
        England,
        India,
        NewZealand,
        Pakistan,
        SouthAfrica,
        SriLanka,
        WestIndies,
        Bangladesh,
        Zimbabwe,
        MCC = 167,
        Lancashire = 301,
        Warwickshire,
        Durham,
        Somerset,
        Sussex,
        Nottinghamshire,
        Worcestershire,
        Middlesex,
        Surrey,
        Yorkshire,
        Hampshire,
        Northamptonshire,
        Gloucestershire,
        Derbyshire,
        Glamorgan,
        Essex,
        Kent,
        Leicestershire,
        NotValid = -1
    };

    public enum ODIWCTeamCode : int
    {
        England = 389,
        SouthAfrica,
        SriLanka,
        Pakistan,
        Bangladesh,
        Ireland,
        Kenya,
        Australia,
        India,
        NewZealand,
        WestIndies,
        Zimbabwe,
        Netherlands,
        UAE,
        NotValid = -1
    };

    public enum T20WCTeamCode : int
    {
        England = 405,
        India,
        Afghanistan,
        Australia,
        WestIndies,
        Ireland,
        SriLanka,
        SouthAfrica,
        Zimbabwe,
        Pakistan,
        NewZealand,
        Bangladesh,
        NotValid = -1
    };
}
